package org.sems.sems.ConfigController;

import org.sems.sems.entity.Dhjlk;
import org.sems.sems.entity.Aidhjlk;
import org.sems.sems.entity.ChatMessage;
import org.sems.sems.entity.AiMessage;
import org.sems.sems.service.SstXService;
import org.sems.sems.service.AiHistoryService;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.messaging.handler.annotation.MessageMapping;
import org.springframework.messaging.simp.SimpMessagingTemplate;
import org.springframework.stereotype.Controller;

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * WebSocket 控制器，处理普通聊天和 AI 问答，两者互不影响：
 *  - /app/chat  处理普通聊天，保存 Dhjlk
 *  - /app/chat2 处理 AI 聊天，支持上下文记忆
 */
@Controller
public class ChatController {

    private final SimpMessagingTemplate messagingTemplate;
    private final SstXService sstXService;
    private final AiHistoryService aiHistoryService;

    // HttpClient 用于发送 HTTP 请求
    private static final HttpClient httpClient = HttpClient.newHttpClient();

    @Value("${openai.api.key}")
    private String apiKey;

    @Value("${openai.api.base:https://api.chatanywhere.com.cn/v1}")
    private String apiBase;

    public ChatController(SimpMessagingTemplate messagingTemplate,
                          SstXService sstXService,
                          AiHistoryService aiHistoryService) {
        this.messagingTemplate = messagingTemplate;
        this.sstXService = sstXService;
        this.aiHistoryService = aiHistoryService;
    }

    /**
     * 处理前端发送到 /app/chat 的普通聊天消息：
     * 1. 保存聊天记录到数据库（Dhjlk）
     * 2. 广播到所有订阅 /topic/messages 的客户端
     */
    @MessageMapping("/chat")
    public void handleChat(ChatMessage message) {
        System.out.println("收到普通聊天消息: " + message);

        Dhjlk dhjlk = new Dhjlk();
        dhjlk.setFromyhm(message.fromyhm());
        dhjlk.setToyhm(message.toyhm());
        dhjlk.setFromyhsfdm(message.fromyhsfdm());
        dhjlk.setToyhsfdm(message.toyhsfdm());
        dhjlk.setQydm(1);
        dhjlk.setIsqf(message.isqf());
        dhjlk.setNr(message.nr());
        dhjlk.setSendtime(new Date());
        sstXService.addNewlxr(dhjlk);

        messagingTemplate.convertAndSend("/topic/messages", message);
    }

    /**
     * 处理前端发送到 /app/chat2 的 AI 问答消息：
     * 支持对话历史记忆：
     * 1. 回显“正在思考”提示
     * 2. 读取历史上下文并拼装请求
     * 3. 流式调用 OpenAI 接口并逐段广播
     * 4. 完成后保存完整对话到 AIDHJLK
     */
    @MessageMapping("/chat2")
    public void handleChat2(AiMessage aiMessage) {
        // 1. 回显“正在思考”提示
        messagingTemplate.convertAndSend(
                "/topic/messages",
                aiMessage.withAnswer("…正在为您思考，请稍候…")
        );

        // 异步处理，避免阻塞 WebSocket 线程
        new Thread(() -> {
            StringBuilder accumulated = new StringBuilder();
            try {
                // 2. 从数据库读取最近 5 条历史对话
                List<Aidhjlk> history = aiHistoryService.findRecentAidhjlkByUser(
                        aiMessage.twzyhm(), 2
                );
                Collections.reverse(history);

                // 3. 构造 OpenAI 请求消息列表
                List<Map<String,String>> messages = new ArrayList<>();
                for (Aidhjlk h : history) {
                    messages.add(Map.of("role", "user",      "content", h.getWtnr()));
                    messages.add(Map.of("role", "assistant", "content", h.getAihd()));
                }
                // 添加当前用户提问
                messages.add(Map.of("role", "user", "content", aiMessage.question()));

                String requestBody = buildRequestBody(messages);

                // 4. 发起流式调用
                HttpRequest request = HttpRequest.newBuilder()
                        .uri(URI.create(apiBase + "/chat/completions"))
                        .header("Authorization", "Bearer " + apiKey)
                        .header("Content-Type", "application/json")
                        .POST(HttpRequest.BodyPublishers.ofString(requestBody))
                        .build();

                HttpResponse<InputStream> response = httpClient.send(
                        request, HttpResponse.BodyHandlers.ofInputStream()
                );

                // 正则匹配 JSON 中的 content 字段
                Pattern p = Pattern.compile("\\\"content\\\":\\\"(.*?)\\\"");
                try (BufferedReader reader = new BufferedReader(
                        new InputStreamReader(response.body()))) {
                    String line;
                    while ((line = reader.readLine()) != null) {
                        if (!line.startsWith("data: ")) continue;
                        String json = line.substring(6).trim();
                        if ("[DONE]".equals(json)) break;

                        Matcher m = p.matcher(json);
                        if (m.find()) {
                            String chunk = m.group(1)
                                    .replace("\\\"", "\"")
                                    .replace("\\\\", "\\");
                            accumulated.append(chunk);

                            // 逐段广播当前内容
                            AiMessage partial = new AiMessage(
                                    aiMessage.twzyhm(),
                                    aiMessage.twzsfdm(),
                                    aiMessage.twzyzxm(),
                                    aiMessage.question(),
                                    accumulated.toString(),
                                    new Date()
                            );
                            messagingTemplate.convertAndSend(
                                    "/topic/messages", partial
                            );
                        }
                    }
                }

                // 5. 保存完整对话记录
                Aidhjlk record = new Aidhjlk();
                record.setTwz(aiMessage.twzyhm());
                record.setTwzfdm(Integer.valueOf(aiMessage.twzsfdm()));
                record.setWtnr(aiMessage.question());
                record.setAihd(accumulated.toString());
                record.setTwsj(new Date());
                aiHistoryService.saveAidhjlk(record);

            } catch (Exception e) {
                e.printStackTrace();
                // 出错时广播错误消息
                AiMessage error = aiMessage.withAnswer("AI 调用失败：" + e.getMessage());
                messagingTemplate.convertAndSend(
                        "/topic/messages", error
                );
            }
        }).start();
    }

    /**
     * 构建 OpenAI Chat Completion 请求体，启用流式返回
     */
    private String buildRequestBody(List<Map<String,String>> messages) {
        StringBuilder sb = new StringBuilder();
        sb.append("{\"model\":\"gpt-4o\",\"stream\":true,\"messages\":[");
        for (Map<String,String> msg : messages) {
            String content = msg.get("content")
                    .replace("\\", "\\\\")
                    .replace("\"", "\\\"");
            sb.append(String.format(
                    "{\"role\":\"%s\",\"content\":\"%s\"},",
                    msg.get("role"), content
            ));
        }
        if (!messages.isEmpty()) sb.deleteCharAt(sb.length() - 1);
        sb.append("]}");
        return sb.toString();
    }
}